home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / muds / mordor_2.000 / mordor_2 / src / command7.c < prev    next >
C/C++ Source or Header  |  1995-04-20  |  17KB  |  674 lines

  1. /*
  2.  * COMMAND7.C:
  3.  *
  4.  *    Additional user routines.
  5.  *
  6.  *    Copyright (C) 1991, 1992, 1993 Brett J. Vickers
  7.  *
  8.  */
  9.  
  10. #include "mstruct.h"
  11. #include "mextern.h"
  12.  
  13. /**********************************************************************/
  14. /*                flee                      */
  15. /**********************************************************************/
  16.  
  17. /* This function allows a player to flee from an enemy.  If successful */
  18. /* the player will drop his readied weapon and run through one of the  */
  19. /* visible exits, losing 10% or 1000 experience, whichever is less.    */
  20.  
  21. int flee(ply_ptr, cmnd)
  22. creature    *ply_ptr;
  23. cmd        *cmnd;
  24. {
  25.     room    *rom_ptr;
  26.     xtag    *xp;
  27.     ctag    *cp, *temp;
  28.     char     found = 0;
  29.     int    fd, n;
  30.     long    i, t;
  31.  
  32.     rom_ptr = ply_ptr->parent_rom;
  33.     fd = ply_ptr->fd;
  34.  
  35.     t = time(0);
  36.     i = MAX(ply_ptr->lasttime[LT_ATTCK].ltime,
  37.         ply_ptr->lasttime[LT_SPELL].ltime) + 3L;
  38.  
  39.     if(t < i && !F_ISSET(ply_ptr, PFEARS)) {
  40.         please_wait(fd, i-t);
  41.         return(0);
  42.     }
  43.         t = Time%24L;
  44.     xp = rom_ptr->first_ext;
  45.     if(xp) do {
  46.         if(F_ISSET(xp->ext, XCLOSD)) continue;
  47.         if((F_ISSET(xp->ext, XCLIMB) || F_ISSET(xp->ext, XDCLIM)) &&  
  48. (!F_ISSET(ply_ptr, PLEVIT))) continue; 
  49.         if(F_ISSET(xp->ext, XNAKED) && weight_ply(ply_ptr)) continue;
  50.         if(F_ISSET(xp->ext, XFEMAL) && F_ISSET(ply_ptr, PMALES)) continue;
  51.         if(F_ISSET(xp->ext, XMALES) && !F_ISSET(ply_ptr, PMALES)) continue; 
  52.         if(F_ISSET(xp->ext, XFLYSP) && !F_ISSET(ply_ptr, PFLYSP))
  53.             continue;
  54.         if(!F_ISSET(ply_ptr, PDINVI) && F_ISSET(xp->ext, XINVIS))
  55.             continue;
  56.         if(F_ISSET(xp->ext, XSECRT)) continue;
  57.         if(F_ISSET(xp->ext, XNOSEE)) continue;
  58.     if(F_ISSET(xp->ext, XPLDGK)) 
  59.         if (!F_ISSET(ply_ptr, PPLDGK)) continue;
  60.         else if (BOOL(F_ISSET(xp->ext,XKNGDM)) !=  BOOL(F_ISSET(ply_ptr, PKNGDM))) 
  61.             continue;
  62.         if(F_ISSET(xp->ext, XNGHTO) && (t>6 && t < 20)) continue;
  63.         if(F_ISSET(xp->ext, XDAYON) && (t<6 || t > 20))  continue;
  64.         
  65.     if(F_ISSET(xp->ext,XPGUAR)){
  66.         cp = rom_ptr->first_mon;
  67.         while(cp) {
  68.             if(F_ISSET(cp->crt, MPGUAR) && 
  69.             !F_ISSET(ply_ptr, PINVIS) && ply_ptr->class < CARETAKER) {
  70.         found = 1;
  71.         break;
  72.             }
  73.             cp = cp->next_tag;
  74.         }
  75.     if(found)
  76.         continue;
  77.     }         
  78. /* if(mrand(1,100) < 70) break;     */
  79.         if(mrand(1,100) < (65 + bonus[ply_ptr->dexterity]*5)) 
  80.             break;
  81.     } while(xp = xp->next_tag);
  82.  
  83.      
  84.         if(xp && F_ISSET(xp->ext,52) && mrand(1,5) < 2 && !F_ISSET(ply_ptr, PFEARS))
  85.         xp = 0;
  86.     if(!xp) {
  87.         print(fd, "You failed to escape!\n");
  88.         return(0);
  89.     }
  90.  
  91.     if(ply_ptr->ready[WIELD-1] &&
  92.        !F_ISSET(ply_ptr->ready[WIELD-1], OCURSE)) {
  93.         add_obj_rom(ply_ptr->ready[WIELD-1], rom_ptr);
  94.         ply_ptr->ready[WIELD-1] = 0;
  95.         compute_thaco(ply_ptr);
  96.         compute_ac(ply_ptr);
  97.         print(fd, "You drop your weapon and run like a chicken.\n");
  98.     }
  99.     else
  100.         print(fd, "You run like a chicken.\n");
  101.  
  102.     F_CLR(ply_ptr, PHIDDN);
  103.  
  104.     if(F_ISSET(ply_ptr, PFEARS)) {
  105.         ANSI(fd, RED);
  106.         print(fd, "You flee in fear!\n");
  107.         ANSI(fd, WHITE);
  108.     }
  109.  
  110.     
  111.     if(!F_ISSET(rom_ptr, RPTRAK))
  112.         strcpy(rom_ptr->track, xp->ext->name);
  113.  
  114.     broadcast_rom(fd, rom_ptr->rom_num, "%M flees to the %s.", 
  115.               ply_ptr, xp->ext->name);
  116.  
  117.     if (ply_ptr->class == PALADIN)
  118.         if (ply_ptr->level > 5) {
  119.         n = ply_ptr->level*15;
  120.         n = MIN(ply_ptr->experience, n);
  121.         print(fd,"You lose %d experience for your cowardly retreat.\n",n);
  122.         ply_ptr->experience -= n;
  123.         lower_prof(ply_ptr,n);
  124.     }
  125.  
  126.     load_rom(xp->ext->room, &rom_ptr);
  127.  
  128.     if(rom_ptr->lolevel > ply_ptr->level || 
  129.        (ply_ptr->level > rom_ptr->hilevel && rom_ptr->hilevel)) {
  130.         print(fd, "You are thrown back by an invisible force.\n");
  131.         broadcast_rom(fd, rom_ptr->rom_num, "%M just arrived.",ply_ptr);
  132.         return(0);
  133.     }
  134.  
  135.     n = count_vis_ply(rom_ptr);
  136.     if((F_ISSET(rom_ptr, RONEPL) && n > 0) ||
  137.        (F_ISSET(rom_ptr, RTWOPL) && n > 1) ||
  138.        (F_ISSET(rom_ptr, RTHREE) && n > 2)) {
  139.         print(fd, "The room you fled to was full!\n");
  140.         broadcast_rom(fd, rom_ptr->rom_num, "%M just arrived.",ply_ptr);
  141.         return(0);
  142.     }
  143.  
  144.     del_ply_rom(ply_ptr, ply_ptr->parent_rom);
  145.     add_ply_rom(ply_ptr, rom_ptr);
  146.  
  147.     check_traps(ply_ptr, rom_ptr);
  148.  
  149.     return(0);
  150.  
  151. }
  152.  
  153. /**********************************************************************/
  154. /*                list                      */
  155. /**********************************************************************/
  156.  
  157. /* This function allows a player to list the items for sale within a */
  158. /* shoppe.                                 */
  159.  
  160. int list(ply_ptr, cmnd)
  161. creature    *ply_ptr;
  162. cmd        *cmnd;
  163. {
  164.     room    *rom_ptr, *dep_ptr;
  165.     otag    *op;
  166.     int    fd;
  167.  
  168.     fd = ply_ptr->fd;
  169.     rom_ptr = ply_ptr->parent_rom;
  170.  
  171.     if(F_ISSET(rom_ptr, RSHOPP)) {
  172.         if(load_rom(rom_ptr->rom_num+1, &dep_ptr) < 0) {
  173.             print(fd, "Nothing to buy.\n");
  174.             return(0);
  175.         }
  176.  
  177.         print(fd, "You may buy:\n");
  178.         op = dep_ptr->first_obj;
  179.         while(op) {
  180.             print(fd, "   %-30s   Cost: %ld\n", 
  181.                   obj_str(op->obj, 1, CAP), op->obj->value);
  182.             op = op->next_tag;
  183.         }
  184.         print(fd, "\n");
  185.     }
  186.  
  187.     else
  188.         print(fd, "This is not a shoppe.\n");
  189.  
  190.     return(0);
  191.  
  192. }
  193.  
  194. /**********************************************************************/
  195. /*                buy                      */
  196. /**********************************************************************/
  197.  
  198. /* This function allows a player to buy something from a shoppe.      */
  199.  
  200. int buy(ply_ptr, cmnd)
  201. creature    *ply_ptr;
  202. cmd        *cmnd;
  203. {
  204.     room    *rom_ptr, *dep_ptr;
  205.     object    *obj_ptr, *obj_ptr2;
  206.     int    fd;
  207.  
  208.     fd = ply_ptr->fd;
  209.     rom_ptr = ply_ptr->parent_rom;
  210.  
  211.     if(!F_ISSET(rom_ptr, RSHOPP)) {
  212.         print(fd, "This is not a shoppe.\n");
  213.         return(0);
  214.     }
  215.  
  216.     if(cmnd->num < 2) {
  217.         print(fd, "Buy what?\n");
  218.         return(0);
  219.     }
  220.  
  221.     if(load_rom(rom_ptr->rom_num+1, &dep_ptr) < 0) {
  222.         print(fd, "Nothing to buy.\n");
  223.         return(0);
  224.     }
  225.  
  226.     obj_ptr = find_obj(ply_ptr, dep_ptr->first_obj,
  227.                cmnd->str[1], cmnd->val[1]);
  228.  
  229.     if(!obj_ptr) {
  230.         print(fd, "That's not being sold.\n");
  231.         return(0);
  232.     }
  233.  
  234.     if(ply_ptr->gold < obj_ptr->value) {
  235.         print(fd, "You don't have enough gold.\n");
  236.         return(0);
  237.     }
  238.  
  239.                 if(weight_ply(ply_ptr) + weight_obj(obj_ptr) > 
  240.                    max_weight(ply_ptr)) {
  241.                    print(fd, "You can't carry anymore.\n");
  242.                    return(0);
  243.                }             
  244.  
  245.     obj_ptr2 = (object *)malloc(sizeof(object));
  246.     if(!obj_ptr2)
  247.         merror("buy", FATAL);
  248.  
  249.     F_CLR(ply_ptr, PHIDDN);
  250.  
  251.     *obj_ptr2 = *obj_ptr;
  252.     F_CLR(obj_ptr2, OPERM2);
  253.     F_CLR(obj_ptr2, OPERMT);
  254.     F_CLR(obj_ptr2, OTEMPP);
  255.  
  256.     add_obj_crt(obj_ptr2, ply_ptr);
  257.     ply_ptr->gold -= obj_ptr2->value;
  258.     print(fd, "Bought.\n");
  259.     broadcast_rom(fd, ply_ptr->rom_num, "%M bought %1i.", 
  260.               ply_ptr, obj_ptr2);
  261.  
  262.     return(0);
  263.  
  264. }
  265.  
  266. /**********************************************************************/
  267. /*                sell                      */
  268. /**********************************************************************/
  269.  
  270. /* This function will allow a player to sell an object in a pawn shoppe */
  271.  
  272. int sell(ply_ptr, cmnd)
  273. creature    *ply_ptr;
  274. cmd        *cmnd;
  275. {
  276.     room    *rom_ptr;
  277.     object    *obj_ptr;
  278.     int    gold, fd, poorquality = 0;
  279.  
  280.     fd = ply_ptr->fd;
  281.     rom_ptr = ply_ptr->parent_rom;
  282.  
  283.     if(!F_ISSET(rom_ptr, RPAWNS)) {
  284.         print(fd, "This is not a pawn shoppe.\n");
  285.         return(0);
  286.     }
  287.  
  288.     if(cmnd->num < 2) {
  289.         print(fd, "Sell what?\n");
  290.         return(0);
  291.     }
  292.  
  293.     F_CLR(ply_ptr, PHIDDN);
  294.  
  295.     obj_ptr = find_obj(ply_ptr, ply_ptr->first_obj,
  296.                cmnd->str[1], cmnd->val[1]);
  297.  
  298.     if(!obj_ptr) {
  299.         print(fd, "You don't have that.\n");
  300.         return(0);
  301.     }
  302.  
  303.     gold = MIN(obj_ptr->value / 2, 10000);
  304.  
  305.     if((obj_ptr->type <= MISSILE || obj_ptr->type == ARMOR) &&
  306.        obj_ptr->shotscur <= obj_ptr->shotsmax/8)
  307.         poorquality = 1;
  308.  
  309.     if((obj_ptr->type == WAND || obj_ptr->type == KEY) && obj_ptr->shotscur < 1)
  310.         poorquality = 1;
  311.  
  312.     if(gold < 20 || poorquality) {
  313.         print(fd, "The shopkeep says, \"I won't buy that crap.\"\n");
  314.         return(0);
  315.     }
  316.  
  317.     if(obj_ptr->type == SCROLL || obj_ptr->type == POTION) {
  318.         print(fd, "The shopkeep won't buy potions and scrolls.\n");
  319.         return(0);
  320.     }
  321.  
  322.     print(fd, "The shopkeep gives you %d gold for %i.\n", gold, obj_ptr);
  323.     broadcast_rom(fd, ply_ptr->rom_num, "%M sells %1i.", 
  324.               ply_ptr, obj_ptr);
  325.  
  326.     ply_ptr->gold += gold;
  327.     del_obj_crt(obj_ptr, ply_ptr);
  328.     free_obj(obj_ptr);
  329.  
  330.     return(0);
  331.  
  332. }
  333.  
  334. /**********************************************************************/
  335. /*                value                      */
  336. /**********************************************************************/
  337.  
  338. /* This function allows a player to find out the pawn-shop value of an */
  339. /* object, if he is in the pawn shop.                       */
  340.  
  341. int value(ply_ptr, cmnd)
  342. creature    *ply_ptr;
  343. cmd        *cmnd;
  344. {
  345.     room    *rom_ptr;
  346.     object    *obj_ptr;
  347.     long    value;
  348.     int    fd;
  349.  
  350.     fd = ply_ptr->fd;
  351.     rom_ptr = ply_ptr->parent_rom;
  352.  
  353.     if(!F_ISSET(rom_ptr, RPAWNS) && !F_ISSET(rom_ptr, RREPAI)) {
  354.         print(fd, "You must be in a pawn or repair shoppe.\n");
  355.         return(0);
  356.     }
  357.  
  358.     if(cmnd->num < 2) {
  359.         print(fd, "Value what?\n");
  360.         return(0);
  361.     }
  362.  
  363.     F_CLR(ply_ptr, PHIDDN);
  364.  
  365.     obj_ptr = find_obj(ply_ptr, ply_ptr->first_obj,
  366.                cmnd->str[1], cmnd->val[1]);
  367.  
  368.     if(!obj_ptr) {
  369.         print(fd, "You don't have that.\n");
  370.         return(0);
  371.     }
  372.  
  373.     if(F_ISSET(rom_ptr, RPAWNS)) {
  374.         value = MIN(obj_ptr->value / 2, 10000L);
  375.         print(fd, "The shopkeep says, \"%I's worth %ld.\"\n",
  376.               obj_ptr, value);
  377.     }
  378.     else {
  379.         value = obj_ptr->value / 2;
  380.         print(fd, 
  381.               "The shopkeep says, \"%I costs %ld to be repaired.\"\n", 
  382.               obj_ptr, value);
  383.     }
  384.  
  385.     broadcast_rom(fd, ply_ptr->rom_num, "%M gets %i appraised.",
  386.               ply_ptr, obj_ptr);
  387.  
  388.     return(0);
  389.  
  390. }
  391.  
  392. /**********************************************************************/
  393. /*                backstab                  */
  394. /**********************************************************************/
  395.  
  396. /* This function allows thieves and assassins to backstab a monster.  */
  397. /* If successful, a damage multiplier is given to the player.  The    */
  398. /* player must be successfully hidden for the backstab to work.  If   */
  399. /* the backstab fails, then the player is forced to wait double the   */
  400. /* normal amount of time for his next attack.                  */
  401.  
  402. int backstab(ply_ptr, cmnd)
  403. creature    *ply_ptr;
  404. cmd        *cmnd;
  405. {
  406.     creature    *crt_ptr;
  407.     room        *rom_ptr;
  408.     long        i, t;
  409.     int        fd, m, n, p, addprof;
  410.  
  411.     fd = ply_ptr->fd;
  412.     rom_ptr = ply_ptr->parent_rom;
  413.  
  414.     if(ply_ptr->class != THIEF && ply_ptr->class != ASSASSIN &&
  415.        ply_ptr->class < CARETAKER) {
  416.         print(fd, "Only thieves and assassins may backstab.\n");
  417.         return(0);
  418.     }
  419.  
  420.     if(cmnd->num < 2 || F_ISSET(ply_ptr, PBLIND)) {
  421.         print(fd, "Backstab what?\n");
  422.         return(0);
  423.     }
  424.  
  425.     if(!ply_ptr->ready[WIELD-1] || (ply_ptr->ready[WIELD-1]->type 
  426.        != SHARP && ply_ptr->ready[WIELD-1]->type != THRUST)) {
  427.         print(fd, "Backstab requires sharp or thrusting weapons.\n");
  428.         return(0);
  429.     }
  430.  
  431.     t = time(0);
  432.     i = LT(ply_ptr, LT_ATTCK);
  433.  
  434.     if(t < i) {
  435.         please_wait(fd, i-t);
  436.         return(0);
  437.     }
  438.  
  439.     crt_ptr = find_crt(ply_ptr, rom_ptr->first_mon,
  440.                cmnd->str[1], cmnd->val[1]);
  441.  
  442.     if(!crt_ptr) {
  443.         cmnd->str[1][0] = up(cmnd->str[1][0]);
  444.         crt_ptr = find_crt(ply_ptr, rom_ptr->first_ply,
  445.                    cmnd->str[1], cmnd->val[1]);
  446.  
  447.         if(!crt_ptr || crt_ptr == ply_ptr || strlen(cmnd->str[1]) < 3) {
  448.             print(fd, "You don't see that here.\n");
  449.             return(0);
  450.         }
  451.  
  452.     }
  453.  
  454.     if(crt_ptr->type != PLAYER && is_enm_crt(ply_ptr->name, crt_ptr)) {
  455.         print(fd, "Not while you're already fighting %s.\n",
  456.               F_ISSET(crt_ptr, MMALES) ? "him":"her");
  457.         return(0);
  458.     }
  459.  
  460.     if(crt_ptr->type == PLAYER) {
  461.         if(F_ISSET(rom_ptr, RNOKIL)) {
  462.             print(fd, "No killing allowed in this room.\n");
  463.             return(0);
  464.         }
  465.  
  466.             if((!F_ISSET(ply_ptr,PPLDGK) || !F_ISSET(crt_ptr,PPLDGK)) ||
  467.                 (BOOL(F_ISSET(ply_ptr,PKNGDM)) == BOOL(F_ISSET(crt_ptr,PKNGDM))) ||
  468.                 (! AT_WAR)) {
  469.                 if(!F_ISSET(ply_ptr, PCHAOS)) {
  470.                     print(fd, "Sorry, you're lawful.\n");
  471.                     return (0);
  472.                 }
  473.                 if(!F_ISSET(crt_ptr, PCHAOS)) {
  474.                     print(fd, "Sorry, that player is lawful.\n");
  475.                     return (0);
  476.                 }     
  477.         if(is_charm_crt(ply_ptr->name, crt_ptr) && F_ISSET(ply_ptr, PCHARM)){
  478.             print (fd, "Why would you want to backstab your good friend %s?\n", crt_ptr->name);
  479.             return(0);
  480.         }
  481.             }
  482.  
  483.         print(crt_ptr->fd, "%M backstabs you.\n", ply_ptr);
  484.     }
  485.     else if(F_ISSET(crt_ptr, MUNKIL)) {
  486.         print(fd, "You cannot harm %s.\n",
  487.             F_ISSET(crt_ptr, MMALES) ? "him":"her");
  488.         return(0);
  489.     }
  490.     if(is_charm_crt(crt_ptr->name, ply_ptr) && F_ISSET(ply_ptr, PCHARM)) {
  491.                 print(fd, "You are too fond of %s to do that.\n", crt_ptr->name);
  492.                 return(0);
  493.         }
  494.  
  495.     if(F_ISSET(ply_ptr, PINVIS)) {
  496.         F_CLR(ply_ptr, PINVIS);
  497.         print(fd, "Your invisibility fades.\n");
  498.         broadcast_rom(fd, ply_ptr->rom_num, "%M fades into view.",
  499.                   ply_ptr);
  500.     }
  501.  
  502.     ply_ptr->lasttime[LT_ATTCK].ltime = t;
  503.     if(ply_ptr->dexterity > 18)
  504.         ply_ptr->lasttime[LT_ATTCK].interval = 2;
  505.     else
  506.         ply_ptr->lasttime[LT_ATTCK].interval = 3;
  507.  
  508.     if(crt_ptr->type != PLAYER) {
  509.         if(add_enm_crt(ply_ptr->name, crt_ptr) < 0) {
  510.             print(fd, "You backstab %m.\n", crt_ptr);
  511.             broadcast_rom2(fd, crt_ptr->fd, ply_ptr->rom_num, 
  512.                        "%M backstabs %m.", ply_ptr, crt_ptr);
  513.              if(F_ISSET(crt_ptr, MMGONL)) {
  514.                 print(fd, "Your weapon has no effect on %m.\n", crt_ptr);
  515.                 return(0);
  516.             }
  517.             if(F_ISSET(crt_ptr, MENONL)) {
  518.                 if(!ply_ptr->ready[WIELD-1] || 
  519.                     ply_ptr->ready[WIELD-1]->adjustment < 1) {
  520.                     print(fd, "Your weapon has no effect on %m.\n", crt_ptr);
  521.                     return(0);
  522.             }
  523.         }  
  524.  
  525.         }
  526.     }
  527.     else {
  528.         print(fd, "You backstab %m.\n", crt_ptr);
  529.         print(crt_ptr->fd, "%M backstabs you.\n", ply_ptr);
  530.         broadcast_rom2(fd, crt_ptr->fd, ply_ptr->rom_num, 
  531.                    "%M backstabs %m!", ply_ptr, crt_ptr);
  532.     }
  533.  
  534.     if(ply_ptr->ready[WIELD-1]) {
  535.         if(ply_ptr->ready[WIELD-1]->shotscur < 1) {
  536.             print(fd, "Your %s is broken.\n", 
  537.                   ply_ptr->ready[WIELD-1]->name);
  538.             add_obj_crt(ply_ptr->ready[WIELD-1], ply_ptr);
  539.             ply_ptr->ready[WIELD-1] = 0;
  540.             broadcast_rom(fd, ply_ptr->rom_num, 
  541.                       "%s backstab failed.", 
  542.                       F_ISSET(ply_ptr, PMALES) ? "His":"Her");
  543.             ply_ptr->lasttime[LT_ATTCK].interval *= 2;
  544.             return(0);
  545.         }
  546.     }
  547.  
  548.     n = ply_ptr->thaco - crt_ptr->armor/10 + 2;
  549.     if(!F_ISSET(ply_ptr, PHIDDN))
  550.         n = 21;
  551.  
  552.     F_CLR(ply_ptr, PHIDDN);
  553.  
  554.     if(mrand(1,20) >= n) {
  555.         if(ply_ptr->ready[WIELD-1])
  556.             n = mdice(ply_ptr->ready[WIELD-1]);
  557.         else
  558.             n = mdice(ply_ptr);
  559.  
  560.         if(ply_ptr->class == THIEF)
  561.             n *= (mrand(20,35) / 10);
  562.         else
  563.             n *= 3;
  564.  
  565.         m = MIN(crt_ptr->hpcur, n);
  566.         if(crt_ptr->type != PLAYER) {
  567.             add_enm_dmg(ply_ptr->name, crt_ptr, m);
  568.             if(ply_ptr->ready[WIELD-1]) {
  569.                 p = MIN(ply_ptr->ready[WIELD-1]->type, 4);
  570.                 addprof = (m * crt_ptr->experience) /
  571.                     crt_ptr->hpmax;
  572.                 addprof = MIN(addprof, crt_ptr->experience);
  573.                 ply_ptr->proficiency[p] += addprof;
  574.             }
  575.         }
  576.         crt_ptr->hpcur -= n;
  577.  
  578.         print(fd, "You hit for %d damage.\n", n);
  579.         print(crt_ptr->fd, "%M hit you for %d damage.\n", ply_ptr, n);
  580.  
  581.         if(crt_ptr->hpcur < 1) {
  582.             print(fd, "You killed %m.\n", crt_ptr);
  583.             broadcast_rom(fd, ply_ptr->rom_num,
  584.                       "%M killed %m.", ply_ptr, crt_ptr);
  585.             if(ply_ptr->ready[WIELD-1])
  586.                 ply_ptr->ready[WIELD-1]->shotscur--;
  587.             die(crt_ptr, ply_ptr);
  588.         }
  589.         else
  590.             check_for_flee(crt_ptr);
  591.     }
  592.     else {
  593.         print(fd, "You missed.\n");
  594.         broadcast_rom(fd, ply_ptr->rom_num, "%s backstab failed.", 
  595.                   F_ISSET(ply_ptr, PMALES) ? "His":"Her");
  596.         ply_ptr->lasttime[LT_ATTCK].interval *= 3;
  597.     }
  598.  
  599.     return(0);
  600.  
  601. }
  602.  
  603. /**********************************************************************/
  604. /*                train                      */
  605. /**********************************************************************/
  606.  
  607. /* This function allows a player to train if he is in the correct     */
  608. /* training location and has enough gold and experience.  If so, the  */
  609. /* character goes up a level.                          */
  610.  
  611. int train(ply_ptr, cmnd)
  612. creature    *ply_ptr;
  613. cmd        *cmnd;
  614. {
  615.     room    *rom_ptr;
  616.     long    goldneeded, expneeded, lv;
  617.     int    fd, i, fail = 0, bit[4];
  618.  
  619.     fd = ply_ptr->fd;
  620.     
  621.     if(F_ISSET(ply_ptr, PBLIND)){
  622.         ANSI(fd, RED);
  623.         print(fd, "You can't...You're blind!\n");
  624.         ANSI(fd, WHITE);
  625.         return(0);
  626.     }
  627.  
  628.     rom_ptr = ply_ptr->parent_rom;
  629.  
  630.     bit[0] = ply_ptr->class & 1;
  631.     bit[1] = ply_ptr->class & 2;
  632.     bit[2] = ply_ptr->class & 4;
  633.     bit[3] = ply_ptr->class & 8;
  634.  
  635.     for(i=0; i<4; i++) {
  636.         if(!((bit[i] && F_ISSET(rom_ptr, RTRAIN+3-i)) ||
  637.            (!bit[i] && !F_ISSET(rom_ptr, RTRAIN+3-i))))
  638.             fail = 1;
  639.     }
  640.  
  641.     if(fail) {
  642.         print(fd, "This is not your training location.\n");
  643.         return(0);
  644.     }
  645.  
  646.     if(ply_ptr->level < MAXALVL)
  647.         expneeded = needed_exp[ply_ptr->level-1];
  648.     else
  649.                expneeded = (long)((needed_exp[MAXALVL-1]*ply_ptr->level));   
  650.  
  651.     goldneeded = expneeded / 2L;
  652.  
  653.     if(expneeded > ply_ptr->experience) {
  654.         print(fd, "You need %ld more experience.\n",
  655.               expneeded - ply_ptr->experience);
  656.         return(0);
  657.     }
  658.  
  659.     if(goldneeded > ply_ptr->gold) {
  660.         print(fd, "You don't have enough gold.\n");
  661.         print(fd, "You need %ld gold to train.\n", goldneeded);
  662.         return(0);
  663.     }
  664.  
  665.     ply_ptr->gold -= goldneeded;
  666.     up_level(ply_ptr);
  667.  
  668.     broadcast("### %s just made a level!", ply_ptr->name);
  669.     print(fd, "Congratulations, you made a level!\n\n");
  670.  
  671.     return(0);
  672.  
  673. }
  674.